/** Modules:
  * 
  * Authors:	Wei Li (oldrev@gmail.com)
  *
  * Copyright:	Copyright (C) 2007 Wei Li. All rights reserved.
  *
  * License:	BSD
  *
  *
  *
  */

module dotmars.text.ascii;

import dotmars.text.encoding;
import dotmars.base.stdtypes;
import dotmars.base.stdexcept;
import dotmars.text.utf;


class ASCIIEncoding : Encoding
{
	public alias Encoding.decode decode;
	public alias Encoding.encode encode;

	public this()
	{
		super();
	}

	public override Encoding clone() {
		auto e = new ASCIIEncoding();
		e = this;
		return e;
	}

	public override char[] encodingName() {
		return "ASCII";
	}

	public override bool isSingleByte(){
		return true;
	}

	public override ubyte[] preamble() {
		return null;
	}

	public override Encoder getEncoder() {
		return super.getEncoder();
	}

	public override Decoder getDecoder() {
		return super.getDecoder();
	}

	//ASCII 仅支持 0~0x7F 的编码，其他字符将丢失
	public override size_t getByteCount(char[] str) 
	in{
		assert(str !is null);
	}
	body{
		return str.length;
	}

	public override size_t getCharCount(ubyte[] bytes)
	in{
		assert(bytes !is null);
	}
	body {
		return bytes.length;
	}

	public override size_t getMaxByteCount(size_t charCount) {
		return charCount;
	}

	public override size_t getMaxCharCount(size_t byteCount) {
		return byteCount;
	}

	public override size_t decode(ubyte[] bytes, Sink!(char) sink) {
		return internalDecode(bytes, sink);
	}
	

	public override size_t encode(char[] chars, Sink!(ubyte) sink) {
		return internalEncode(chars, sink);
	}

	public static bool isASCIIChar(dchar c) {
		return c <= 0x7F;
	}

	public static size_t internalEncode(char[] chars, Sink!(ubyte) sink)
	in{
		assert(chars !is null);
		assert(sink !is null);
	}
	body{
		foreach(char c; chars)
		{
			if(isASCIIChar(c)) 
				sink(cast(ubyte)c);
			else 
				sink('?');
		}
		return chars.length;
	}

	public static size_t internalDecode(ubyte[] bytes, Sink!(char) sink)
	in{
		assert(bytes !is null);
		assert(sink !is null);
	}
	body {
		foreach(ubyte u; bytes) 
		{
			if(isASCIIChar(u)) 
				sink(cast(char)u);
			else 
				sink('?');
		}
		return bytes.length;
	}
}
